var engine, engineCache, engineConfig;
export default {
  _tempInputMap: new Map(),
  userCode: null,
  userAuthorization: null,

  // (cache: IEngineCache, config: IEngineConfig, logic: IEngineLogic): void
  init(cache, config, logic) {
    engine = this;
    engineCache = cache;
    engineConfig = config;
    logic.setEngine(engine);
    Object.assign(engine, logic);
    // 检查本地数据
    // let serveMode = engine.getAccountCache(KEY_SERVERMODE);
    // if (serveMode) {
    //   if (engineConfig.getDebugServer() != serveMode) {
    //     engine.clearAccountCache();
    //   }
    // } else {
    //   if (engine.getAccountCache(KEY_CODE)) {
    //     engine.clearAccountCache();
    //   }
    // }
  },

  // (key: string): any
  getAccountCache(key) {
    if (!key) {
      return null;
    }
    return wx.getStorageSync(key);
  },


  // (): IEngineCache
  getApp() {
    return engineCache;
  },

  // (tag: any, msg?: any): void
  log(tag, msg) {
    if (!engineConfig.isDebugMode() || !tag) {
      return;
    }
    if (msg) {
      console.log("anyfish_" + tag, msg);
    } else {
      console.log("anyfish_log", tag);
    }
  },

  // (): boolean
  isDebugMode() {
    return engineConfig.isDebugMode();
  },

  // (): string
  getCurrentPlatform() {
    return "wx";
  },

  // (): IEngineConfig
  getAppConfig() {
    return engineConfig;
  },

  // (msg: any): void
  toast(msg) {
    if (!msg) {
      return;
    }
    if (typeof msg == "string") {
      wx.showToast({
        icon: "none",
        title: msg
      });
    } else {
      wx.showToast({
        icon: "none",
        title: msg + ""
      });
      console.log(msg);
    }
  },

  // (msg?: string): void
  showLoading(msg) {
    if (msg) {
      wx.showLoading({
        title: typeof msg == "string" ? msg : msg + ""
      });
    } else {
      wx.showLoading();
    }
  },

  // (): void
  hideLoading() {
    wx.hideLoading();
  },

  // (param: IModal, callback?: typeof Callback): void
  showModal(param, callback) {
    if (callback) {
      param.success = function (e) {
        if (e.confirm) {
          callback(true);
        } else if (e.cancel) {
          callback(false, "cancel");
        } else {
          callback(false, "confirm error");
        }
      };
      param.fail = function (reason) {
        callback(false, reason);
      }
    }
    wx.showModal(param);
  },

  showActionSheet(param, callback) {
    if (!param) {
      if (callback) {
        callback(false, "参数错误");
      }
      return;
    }
    if (callback) {
      param.success = function (e) {
        callback(true, e.tapIndex);
      };
      param.fail = function (reason) {
        callback(false, reason);
      }
    }
    wx.showActionSheet(param);
  },

  showScopeWarn(scope, callback) {
    let info;
    if (scope == "scope.userInfo") {
      info = "用户信息";
    } else if (scope == "scope.userLocation") {
      info = "地理位置";
    } else if (scope == "scope.camera") {
      info = "摄像头";
    } else if (scope == "scope.record") {
      info = "录音功能";
    } else if (scope == "scope.writePhotosAlbum") {
      info = "保存图片";
    } else if (scope == "scope.address") {
      info = "通讯地址";
    } else if (scope == "scope.werun") {
      info = "微信运动步数";
    } else {
      if (callback) {
        callback(false, "参数错误");
      }
      return;
    }
    engine.showModal({
      title: "提示",
      content: "您拒绝授权“" + info + "”的权限，将影响部分功能使用，是否重新授权？",
      confirmText: '重新授权'
    }, function (result, reason) {
      if (result) {
        wx.openSetting({
          success(res) {
            if (callback) {
              if (res && res.authSetting[scope]) {
                callback(true);
              } else {
                callback(false, info + "未被授权");
              }
            }
          },
          fail(e) {
            if (callback) {
              callback(false, e);
            }
          }
        });
      } else {
        if (callback) {
          callback(false, reason);
        }
      }
    });
  },

  rpx2px(rpxValue) {
    if (!rpxValue) {
      return 0;
    }
    return wx.getSystemInfoSync().windowWidth / 750 * rpxValue;
  },

  px2rpx(pxValue) {
    if (!pxValue) {
      return 0;
    }
    return 750 / wx.getSystemInfoSync().windowWidth * pxValue;
  },

  // getWindowWidth(): number
  getWindowWidth() {
    return wx.getSystemInfoSync().windowWidth;
  },

  // getWindowHeight(): number
  getWindowHeight() {
    return wx.getSystemInfoSync().windowHeight;
  },

  getWindowRelativeHeight() {
    let info = wx.getSystemInfoSync();
    return 750 / info.windowWidth * info.windowHeight;
  },

  // duration、delay、timingFunction
  createAnimation(param) {
    return wx.createAnimation(param);
  },

  // (title: string): void
  setPageTitle(title) {
    wx.setNavigationBarTitle({
      title: typeof title == "string" ? title : title + ""
    });
  },

  // (): void
  stopPullDownRefresh() {
    wx.stopPullDownRefresh();
  },

  // (text: string, callback?: typeof Callback): void
  setClipboardData(text, callback) {
    wx.setClipboardData({
      data: text,
      success(res) {
        if (callback) {
          callback(true);
        }
      },
      fail(reason) {
        if (callback) {
          callback(false, reason);
        }
      }
    });
  },

  // (callback: typeof StringCallback): void
  getClipboardData(callback) {
    if (!callback) {
      return;
    }
    wx.getClipboardData({
      success(res) {
        callback(true, res.data);
      },
      fail(reason) {
        callback(false, reason);
      }
    });
  },

  // (backPageNum?: number): void
  finishPage(backPageNum) {
    wx.navigateBack({
      delta: backPageNum ? (backPageNum < 0 ? -backPageNum : backPageNum) : 1
    });
  },

  jumpMiniAppPage(appId, isRelease, dest, param, isFinish) {
    if (isFinish) {
      engine.finishPage();
    }
    let path = this.getPagePath(dest, param);
    wx.navigateToMiniProgram({
      appId: appId,
      path: path,
      envVersion: isRelease ? "release" : "trial"
    });
  },

  // (dest: string, param?: object | null, isFinish?: boolean): void
  jumpPage(dest, param, isFinish) {
    if (!dest) {
      return;
    }
    let path = this.getPagePath(dest, param);
    if (isFinish) {
      wx.redirectTo({
        url: path
      });
    } else {
      wx.navigateTo({
        url: path
      });
    }
  },

  jumpHomePage(dest) {
    if (!dest) {
      return;
    }
    wx.switchTab({
      url: dest
    });
  },

  getPagePath(dest, param) {
    let path = dest;
    if (param) {
      let query = null;
      for (let key in param) {
        if (!query) {
          query = "?";
        } else {
          query += "&";
        }
        let value = param[key];
        if (value && typeof value == "object") {
          try {
            value = JSON.stringify(value);
          } catch (e) {}
        }
        query += key + "=" + value;
      }
      if (query) {
        path += query;
      }
    }
    return path;
  },

  // (): object | null
  getPrevPage() {
    let pages = getCurrentPages();
    if (pages && pages.length > 1) {
      return pages[pages.length - 2];
    }
    return null;
  },


  // (key: string, value ? : any): void
  setAccountCache(key, value) {
    if (!key) {
      return;
    }
    if (value != undefined && value != null) {
      wx.setStorageSync(key, value)
    } else {
      wx.removeStorageSync(key);
    }
  },

  // (): void 
  clearAccountCache() {
    engine.userCode = null;
    engine.userAuthorization = null;
    if (engineCache.clearAccountCache) {
      engineCache.clearAccountCache();
    }
    wx.clearStorageSync();
  },

  // (url: string, method: string, param: any, header: object): object
  requestHttpUrl(url, method, param, header, success, fail) {
    let option = {};
    option.url = url;
    option.method = method;
    if (param) {
      option.data = param;
    }
    option.header = header;
    option.success = success;
    option.fail = fail;
    wx.request(option);
  },

  // (url: string, fileName: any, filePath: string, formData: FormData, header: object)
  requestUploadFile(url, fileName, filePath, formData, header, success, fail) {
    let option = {};
    option.url = url;
    option.name = fileName;
    option.filePath = filePath;
    if (formData) {
      option.formData = formData;
    }
    option.header = header;
    option.success = success;
    option.fail = fail;
    wx.uploadFile(option);
  },

  // "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT"
  // (isShowLoading: boolean, url: string, method: string, param: object | null, withoutAccount: boolean, linkId: string): Promise<any>
  requestUrl(isShowLoading, url, method, param, withoutAccount, linkId) {
    return new Promise(function (resolve, reject) {
      if (!url || !method) {
        reject("参数错误");
        return;
      }
      // if (withoutAccount) {
      if (isShowLoading) {
        engine.showLoading();
      }
      engine.requestHttpUrl(url, method, param, engine.getRequestHeader(linkId), function (res) {
        if (engine.requestSuccess(res, isShowLoading, url, param, resolve, reject)) { // 需要重新登录
          reject("请重新授权登录");
        }
      }, function (reason) {
        engine.requestFail(reason, isShowLoading, url, param, reject);
      });
      // } 
      // else {
      //   engine.getAccount(function (data) {
      //     if (!data) {
      //       reject("登录失败，无法获取数据");
      //       return;
      //     }
      //     if (isShowLoading) {
      //       engine.showLoading();
      //     }

      //     engine.requestHttpUrl(url, method, param, engine.getRequestHeader(linkId), function (res) {
      //       if (engine.requestSuccess(res, isShowLoading, url, param, resolve, reject)) { // 需要重新登录
      //         engine.requestUrl(isShowLoading, url, method, param, withoutAccount, linkId).then(data => {
      //           resolve(data);
      //         }).catch(reason => {
      //           reject(reason);
      //         });
      //       }
      //     }, function (reason) {
      //       engine.requestFail(reason, isShowLoading, url, param, reject);
      //     });
      //   });
      // }
    });
  },

  // (isShowLoading: boolean, url: string, param ? : object | null, withoutAccount ? : boolean, linkId ? : string): Promise <any>
  getUrl(isShowLoading, url, param, withoutAccount, linkId) {
    return engine.requestUrl(isShowLoading, url, "GET", param, withoutAccount, linkId);
  },

  // (isShowLoading: boolean, url: string, param ? : object | null, withoutAccount ? : boolean, linkId ? : string): Promise <any>
  postUrl(isShowLoading, url, param, withoutAccount, linkId) {
    return engine.requestUrl(isShowLoading, url, "POST", param, withoutAccount, linkId);
  },

  // (isShowLoading: boolean, url: string, param ? : object | null, withoutAccount ? : boolean, linkId ? : string): Promise <any>
  deleteUrl(isShowLoading, url, param, withoutAccount, linkId) {
    return engine.requestUrl(isShowLoading, url, "DELETE", param, withoutAccount, linkId);
  },

  // (isShowLoading: boolean, url: string, param ? : object | null, withoutAccount ? : boolean, linkId ? : string): Promise <any>
  putUrl(isShowLoading, url, param, withoutAccount, linkId) {
    return engine.requestUrl(isShowLoading, url, "PUT", param, withoutAccount, linkId);
  },

  // (isShowLoading: boolean, url: string, fileName: string, filePath: string, formData: FormData): Promise <any>
  uploadFile(isShowLoading, url, fileName, filePath, formData) {
    if (!fileName && !filePath) {
      return engine.requestUrl(isShowLoading, url, "POST", formData);
    }
    return new Promise(function (resolve, reject) {
      if (!url) {
        reject("参数错误");
        return;
      }
      engine.getAccount(function (data) {
        if (!data) {
          reject("登录失败，无法获取数据");
          return;
        }
        if (isShowLoading) {
          engine.showLoading();
        }
        engine.requestUploadFile(url, fileName, filePath, formData, engine.getUploadFileHeader(), function (res) {
          if (engine.requestSuccess(res, isShowLoading, url, fileName + "_" + filePath, resolve, reject)) { // 需要重新登录
            engine.uploadFile(isShowLoading, url, fileName, filePath, formData).then(data => {
              resolve(data);
            }).catch(reason => {
              reject(reason);
            });
          }
        }, function (reason) {
          engine.requestFail(reason, isShowLoading, url, fileName + "_" + filePath, reject);
        });
      });
    });
  },

  requestFail(reason, isShowLoading, url, param, reject) {
    if (isShowLoading) {
      engine.hideLoading();
    }
    engine.log("requestUrl:", url);
    engine.log("reason:", reason);
    engine.log("requestParam:", param);
    engine.toast("获取数据出错");
    reject("获取数据出错");
  },

  requestSuccess(res, isShowLoading, url, param, resolve, reject) {
    if (isShowLoading) {
      engine.hideLoading();
    }
    if (!res || !res.data) {
      engine.log("requestUrl:", url + "\n res is null");
      engine.log("requestParam:", param);
      engine.toast("获取数据有错");
      reject("获取数据有错");
      return false;
    }
    if (typeof res.data == "string") {
      res.data = res.data.slice(8,-2);
      try {
        res.data = JSON.parse(res.data);
      } catch (e) {
        engine.log("requestUrl:", url);
        engine.log("parse:", res.data);
        engine.log("requestParam:", param);
        engine.toast("获取数据解析有错");
        reject("获取数据解析有错");
        return false;
      }
    }
    resolve(res.data);
    // res = res.data;
    // if (res.status == 502) {
    //   engine.toast("服务器升级中");
    //   reject("服务器升级中");
    //   return false;
    // }
    // if (res.status != 200) {
    //   engine.log("requestUrl:", url + "\n status:" + res.status + " statusMsg:" + res.statusMsg);
    //   engine.log("requestParam:", param);
    //   reject(res.statusMsg);
    //   return false;
    // }
    // let resData = res.res;
    // if (!resData) {
    //   engine.log("requestUrl:", url);
    //   engine.log("res:", res);
    //   engine.log("requestParam:", param);
    //   reject("请求发送失败");
    //   return false;
    // }
    // let code = resData.code;
    // if (code == 1000) {
    //   resolve(resData.data);
    // } else if (code == 500 || code == 2607) { // 过期
    //   engine.log("requestUrl:", url + "\n code:" + code + " codeMsg:" + resData.codeMsg);
    //   engine.log("requestParam:", param);
    //   engine.clearAccountCache();
    //   return true;
    // } else {
    //   engine.log("requestUrl:", url + "\n code:" + code + " codeMsg:" + resData.codeMsg);
    //   engine.log("requestParam:", param);
    //   reject(resData.codeMsg);
    // }
    return false;
  },

  downloadFile(url, callback) {
    if (!url) {
      if (callback) {
        callback(false, "下载路径不能为空");
      }
      return;
    }
    wx.downloadFile({
      url: url,
      success(res) {
        if (callback) {
          callback(true, res.tempFilePath);
        }
      },
      fail(res) {
        if (!res || !res.errMsg) {
          if (callback) {
            callback(false, "保存文件失败");
          }
          return;
        }
        if (callback) {
          callback(false, res.errMsg);
        }
      }
    });
  },

  // (isShowLoading: boolean, param: ILocation, callback: typeof LocationCallback): void
  getLocation(isShowLoading, param, callback) {
    if (!callback) {
      return;
    }
    if (param) {
      if (param.type == undefined || param.type == null) {
        param.type = 1;
      }
    } else {
      param = {
        type: 1
      };
    }
    if (isShowLoading) {
      engine.showLoading();
    }
    wx.getLocation({
      type: "gcj02",
      success(res) {
        if (isShowLoading) {
          engine.hideLoading();
        }
        if (param.type == 0) {
          res.province = "";
          res.city = "";
          res.district = "";
          res.address = "";
          callback(true, res);
          return;
        }
        engine.getAddressByLocation(res.longitude, res.latitude, function (success, data) {
          if (success) {
            if (data) {
              res.province = data.province;
              res.city = data.city;
              res.district = data.district;
              res.country = data.country;
              res.adcode = data.adcode;
              if (param.type == 2) {
                res.address = data.address;
              } else {
                res.address = "";
              }
            } else {
              res.province = "";
              res.city = "";
              res.district = "";
              res.address = "";
            }
            callback(true, res);
          } else {
            res.province = "";
            res.city = "";
            res.district = "";
            res.address = "";
            callback(true, res);
          }
        });
      },
      fail(res) {
        if (isShowLoading) {
          engine.hideLoading();
        }
        if (!res || !res.errMsg) {
          callback(false, "定位失败");
          return;
        }
        if (res.errMsg.indexOf("auth deny") > -1 || res.errMsg.indexOf("auth denied") > -1) {
          engine.showScopeWarn("scope.userLocation", function (isScope) {
            if (isScope) {
              engine.getLocation(isShowLoading, param, callback);
            } else {
              callback(false, res.errMsg);
            }
          });
        } else {
          callback(false, res.errMsg);
        }
      }
    });
  },

  openLocation(param) {
    if (!param) {
      return;
    }
    if (typeof param.longitude == "string") {
      param.longitude = Number(param.longitude);
    }
    if (typeof param.latitude == "string") {
      param.latitude = Number(param.latitude);
    }
    wx.openLocation(param);
  },

  previewImage(param) {
    if (!param || !param.urls) {
      return;
    }
    if (typeof param.current == "number") {
      try {
        param.current = param.urls[param.current];
      } catch (error) {}
    }
    wx.previewImage(param);
  },

  chooseImage(param, callback) {
    if (param) {
      if (param.count == undefined || param.count == null) {
        param.count = 1;
      }
    } else {
      param = {
        count: 1
      };
    }
    if (callback) {
      param.success = function (e) {
        callback(true, e.tempFilePaths);
      };
      param.fail = function (reason) {
        callback(false, reason);
      }
    }
    wx.chooseImage(param);
  },

  // (path: string, callback: typeof Callback): void
  saveImage(path, callback) {
    if (!path) {
      if (callback) {
        callback(false, "图片路径不能为空");
      }
      return;
    }
    if (path.startsWith("http")) {
      wx.getImageInfo({
        src: path,
        success(res) {
          engine.saveImageToPhotosAlbum(res.path, callback);
        },
        fail(reason) {
          if (callback) {
            callback(false, reason);
          }
        }
      });
    } else if (path.startsWith("data:image/png;base64,")) {
      let imageData = path.substring(22, path.length);
      let fileMgr = wx.getFileSystemManager();
      let filePath = wx.env.USER_DATA_PATH + "/" + new Date().getTime() + ".png";
      fileMgr.unlink({
        filePath: filePath,
        complete() {
          fileMgr.writeFile({
            filePath: filePath,
            data: imageData,
            encoding: "base64",
            success() {
              engine.saveImageToPhotosAlbum(filePath, callback, function () {
                fileMgr.unlink({
                  filePath: filePath
                });
              });
            },
            fail(reason) {
              if (callback) {
                callback(false, reason);
              }
            }
          });
        }
      });
    } else {
      engine.saveImageToPhotosAlbum(path, callback);
    }
  },

  saveImageToPhotosAlbum(path, callback, completeCallback) {
    wx.saveImageToPhotosAlbum({
      filePath: path,
      success(res) {
        if (callback) {
          callback(true);
        }
        if (completeCallback) {
          completeCallback();
        }
      },
      fail(res) {
        if (!res || !res.errMsg) {
          if (callback) {
            callback(false, "保存图片失败");
          }
          if (completeCallback) {
            completeCallback();
          }
          return;
        }
        if (res.errMsg.indexOf("auth deny") > -1 || res.errMsg.indexOf("auth denied") > -1) {
          engine.showScopeWarn("scope.writePhotosAlbum", function (isScope) {
            if (isScope) {
              engine.saveImageToPhotosAlbum(path, callback, completeCallback);
            } else {
              if (callback) {
                callback(false, res.errMsg);
              }
              if (completeCallback) {
                completeCallback();
              }
            }
          });
        } else {
          if (callback) {
            callback(false, "保存失败");
          }
          if (completeCallback) {
            completeCallback();
          }
        }
      }
    });
  },

  // (callback: typeof AccountCallback): void
  getAccount(callback) {
    if (!engine.userCode || !engine.userAuthorization) {
      engine.userCode = engine.getAccountCache(KEY_CODE);
      engine.userAuthorization = engine.getAccountCache(KEY_TOKEN);
      if (!engine.userCode || !engine.userAuthorization) {
        engine.handleRequestLogin(callback);
        return;
      }
    }
    if (callback) {
      callback({
        code: engine.userCode,
        token: engine.userAuthorization
      });
    }
  },

  getAccountSession(isShowLoading, callback) {
    if (isShowLoading) {
      engine.showLoading();
    }
    wx.checkSession({
      success() {
        if (isShowLoading) {
          engine.hideLoading();
        }
        let session = engine.getAccountCache(KEY_SESSION);
        if (session) {
          if (callback) {
            callback({
              session: session
            });
          }
        } else {
          engine.handleRequestLogin(callback);
        }
      },
      fail() {
        if (isShowLoading) {
          engine.hideLoading();
        }
        engine.handleRequestLogin(callback);
      }
    });
  },

  getAccountCodeSync() {
    if (engine.userCode) {
      return engine.userCode;
    }
    engine.userCode = engine.getAccountCache(KEY_CODE);
    return engine.userCode;
  },

  getAccountSessionSync() {
    return engine.getAccountCache(KEY_SESSION);
  },

  getMyNameSync() {
    return engine.getAccountCache(KEY_NICKNAME);
  },

  getMyIconSync() {
    return engine.getAccountCache(KEY_AVATARURL);
  },

  getMyPhoneSync() {
    return engine.getAccountCache(KEY_PHONE);
  },

  saveAccount(data) {
    engine.userCode = data.userId;
    engine.userAuthorization = data.token;
    engine.setAccountCache(KEY_CODE, engine.userCode);
    engine.setAccountCache(KEY_TOKEN, engine.userAuthorization);
    engine.setAccountCache(KEY_SESSION, data.session);
    engine.setAccountCache(KEY_SERVERMODE, engineConfig.getDebugServer());
    engine.setAccountCache(KEY_AVATARURL, data.avatarUrl);
    engine.setAccountCache(KEY_NICKNAME, data.nickName);
    engine.setAccountCache(KEY_PHONE, data.phone);
  },

  saveMyName(name) {
    engine.setAccountCache(KEY_NICKNAME, name);
  },

  saveMyIcon(avatarUrl) {
    engine.setAccountCache(KEY_AVATARURL, avatarUrl);
  },

  // 加密数据encryptedData、加密数据的偏移量iv
  getDecryptData(isShowLoading, url, param, callback, isTryAgain) {
    if (!callback) {
      return;
    }
    if (!url || !param) {
      callback(false, "参数错误");
      return;
    }
    engine.getAccountSession(isShowLoading, function (sessionData) {
      if (!sessionData) {
        callback(false, "获取数据失败");
        return;
      }
      param.thirdSession = sessionData.session;
      engine.requestUrl(isShowLoading, url, "POST", param).then(function (data) {
        callback(true, data);
      }).catch(function (reason) {
        if (!isTryAgain && typeof reason == "string" && reason.indexOf("解析") > -1) {
          engine.setAccountCache(KEY_SESSION);
          engine.getDecryptData(isShowLoading, url, param, callback, true);
        } else {
          callback(false, reason);
        }
      });
    });
  },

  getRunData(isShowLoading, callback) {
    if (!callback) {
      return;
    }
    if (isShowLoading) {
      engine.showLoading();
    }
    wx.getWeRunData({
      success(res) {
        if (isShowLoading) {
          engine.hideLoading();
        }
        callback(true, res);
      },
      fail(res) {
        if (isShowLoading) {
          engine.hideLoading();
        }
        if (!res || !res.errMsg) {
          callback(false, "获取步数失败");
          return;
        }
        if (res.errMsg.indexOf("auth deny") > -1 || res.errMsg.indexOf("auth denied") > -1) {
          engine.showScopeWarn("scope.werun", function (isScope) {
            if (isScope) {
              engine.getRunData(isShowLoading, callback);
            } else {
              callback(false, res.errMsg);
            }
          });
        } else {
          callback(false, res.errMsg);
        }
      }
    });
  },

  requestPayment(param, callback) {
    if (!param) {
      if (callback) {
        callback(false, "参数错误");
      }
      return;
    }
    if (callback) {
      param.success = function (e) {
        callback(true);
      }
      param.fail = function (reason) {
        callback(false, reason);
      }
    }
    wx.requestPayment(param);
  },

  makePhoneCall(phoneNumber) {
    if (!phoneNumber) {
      return;
    }
    wx.makePhoneCall({
      phoneNumber: phoneNumber
    });
  },

  scanCode(param, callback) {
    if (!param) {
      param = {};
    }
    if (callback) {
      param.success = function (e) {
        callback(true, e.path);
      }
      param.fail = function (reason) {
        callback(false, reason);
      }
    }
    wx.scanCode(param);
  },

}

const KEY_CODE = "a";
const KEY_TOKEN = "b";
const KEY_SESSION = "c";
const KEY_SERVERMODE = "d";
const KEY_AVATARURL = "e";
const KEY_NICKNAME = "f";
const KEY_PHONE = "g";